<template>
  <div 
    :class="[
      'message-item',
      `message-item--${messagePosition}`,
      { 'message-item--system': message.messageType === 'SYSTEM' }
    ]"
  >
    <!-- 发送者头像 (仅在接收消息时显示) -->
    <div 
      v-if="messagePosition === 'left'" 
      class="message-item__avatar"
    >
      <AvatarImage 
        :src="message.senderAvatarUrl" 
        :alt="message.senderNickname"
        size="small"
      />
    </div>

    <!-- 消息内容区域 -->
    <div class="message-item__content">
      <!-- 发送者昵称 (仅在接收消息时显示) -->
      <div 
        v-if="messagePosition === 'left' && showSenderName" 
        class="message-item__sender"
      >
        {{ message.senderNickname }}
      </div>

      <!-- 消息气泡 -->
      <div 
        :class="[
          'message-item__bubble',
          `message-item__bubble--${message.messageType.toLowerCase()}`,
          { 'message-item__bubble--failed': message.status === 'FAILED' }
        ]"
      >
        <!-- 文本消息 -->
        <div 
          v-if="message.messageType === 'TEXT'" 
          class="message-content message-content--text"
          v-html="formattedTextContent"
        />

        <!-- 图片消息 -->
        <div 
          v-else-if="message.messageType === 'IMAGE'" 
          class="message-content message-content--image"
        >
          <img 
            ref="imageRef"
            :src="currentSrc"
            :alt="'图片消息'"
            class="message-image"
            :class="{
              'lazy-loading': isImageLoading,
              'lazy-loaded': isImageLoaded,
              'lazy-error': hasImageError
            }"
            @click="handleImageClick"
            @error="handleImageError"
            @load="handleImageLoad"
          />
          <div v-if="isImageLoading" class="message-image__loading">
            <i class="el-icon-loading" />
          </div>
          <div v-if="hasImageError" class="message-image__error" @click="retryImageLoad">
            <i class="el-icon-refresh" />
            <span>重试</span>
          </div>
        </div>

        <!-- 文件消息 -->
        <div 
          v-else-if="message.messageType === 'FILE'" 
          class="message-content message-content--file"
          @click="handleFileClick"
        >
          <div class="file-icon">
            <i :class="`file-icon--${getFileIconType(message.content.fileName || '')}`" />
          </div>
          <div class="file-info">
            <div class="file-name">{{ message.content.fileName }}</div>
            <div class="file-size">{{ formatFileSize(message.content.fileSize || 0) }}</div>
          </div>
          <div class="file-download">
            <i class="el-icon-download" />
          </div>
        </div>

        <!-- 语音消息 -->
        <div 
          v-else-if="message.messageType === 'VOICE'" 
          class="message-content message-content--voice"
          @click="handleVoiceClick"
        >
          <div class="voice-icon">
            <i :class="isVoicePlaying ? 'el-icon-video-pause' : 'el-icon-video-play'" />
          </div>
          <div class="voice-duration">
            {{ formatDuration(message.content.duration || 0) }}
          </div>
          <div class="voice-waveform">
            <div 
              v-for="i in 5" 
              :key="i"
              class="voice-wave"
              :class="{ 'voice-wave--active': isVoicePlaying }"
            />
          </div>
        </div>

        <!-- 系统消息 -->
        <div 
          v-else-if="message.messageType === 'SYSTEM'" 
          class="message-content message-content--system"
        >
          {{ message.content.text }}
        </div>

        <!-- 未知消息类型 -->
        <div 
          v-else 
          class="message-content message-content--unknown"
        >
          <i class="el-icon-warning" />
          <span>不支持的消息类型</span>
        </div>
      </div>

      <!-- 消息状态和时间 -->
      <div class="message-item__meta">
        <span class="message-time">{{ formatMessageTime(message.createdAt) }}</span>
        
        <!-- 消息状态指示器 (仅在发送消息时显示) -->
        <div 
          v-if="messagePosition === 'right'" 
          class="message-status"
          :title="getStatusText(message.status)"
        >
          <i 
            v-if="message.status === 'SENDING'" 
            class="el-icon-loading message-status__icon message-status__icon--sending"
          />
          <i 
            v-else-if="message.status === 'SENT'" 
            class="el-icon-check message-status__icon message-status__icon--sent"
          />
          <i 
            v-else-if="message.status === 'DELIVERED'" 
            class="el-icon-check message-status__icon message-status__icon--delivered"
          />
          <div 
            v-else-if="message.status === 'READ'" 
            class="message-status__icon message-status__icon--read"
          >
            <i class="el-icon-check" />
            <i class="el-icon-check" />
          </div>
          <i 
            v-else-if="message.status === 'FAILED'" 
            class="el-icon-warning-outline message-status__icon message-status__icon--failed"
            @click="handleRetryMessage"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { Message } from '@/types'
import { timeFormat, fileFormat, textFormat } from '@/utils/format'
import { useLazyImage } from '@/composables/useLazyImage'
import { APP_CONSTANTS } from '@/utils/constants'
import AvatarImage from './AvatarImage.vue'

// Props
interface Props {
  message: Message
  currentUserId?: number
  showSenderName?: boolean
  showTime?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  showSenderName: true,
  showTime: true
})

// Emits
interface Emits {
  (e: 'imageClick', imageUrl: string): void
  (e: 'fileClick', fileUrl: string, fileName: string): void
  (e: 'voiceClick', voiceUrl: string): void
  (e: 'retryMessage', message: Message): void
}

const emit = defineEmits<Emits>()

// Reactive state
const imageLoading = ref(false)
const isVoicePlaying = ref(false)


// Lazy image loading for message images
const imageSrc = computed(() => {
  if (props.message.messageType === 'IMAGE') {
    return props.message.content.thumbnailUrl || props.message.content.imageUrl || ''
  }
  return ''
})

const lazyImage = useLazyImage(imageSrc.value, {
  placeholder: '/image-placeholder.png',
  errorImage: '/image-error.png',
  rootMargin: '100px',
  threshold: 0.1
})

const {
  imageRef,
  isLoading: isImageLoading,
  isLoaded: isImageLoaded,
  hasError: hasImageError,
  currentSrc,
  retry: retryImageLoad
} = lazyImage

// Computed properties
const messagePosition = computed(() => {
  if (props.message.messageType === 'SYSTEM') return 'center'
  return props.message.fromUserId === props.currentUserId ? 'right' : 'left'
})

const formattedTextContent = computed(() => {
  if (!props.message.content.text) return ''
  
  // 转义HTML防止XSS
  let content = textFormat.escapeHtml(props.message.content.text)
  
  // 处理换行
  content = content.replace(/\n/g, '<br>')
  
  // 处理URL链接
  const urlRegex = /(https?:\/\/[^\s]+)/g
  content = content.replace(urlRegex, '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>')
  
  return content
})

// Methods
const formatMessageTime = (date: Date | string) => {
  return timeFormat.chatTime(date)
}

const formatFileSize = (bytes: number) => {
  return fileFormat.size(bytes)
}

const formatDuration = (seconds: number) => {
  return timeFormat.duration(seconds * 1000)
}

const getFileIconType = (fileName: string) => {
  return fileFormat.typeIcon(fileName)
}

const getStatusText = (status: string) => {
  const statusMap: Record<string, string> = {
    SENDING: '发送中',
    SENT: '已发送',
    DELIVERED: '已送达',
    READ: '已读',
    FAILED: '发送失败，点击重试'
  }
  return statusMap[status] || status
}



const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.src = '/image-error.png'
  imageLoading.value = false
}

const handleImageLoad = () => {
  imageLoading.value = false
}

const handleImageClick = () => {
  if (props.message.content.imageUrl) {
    emit('imageClick', props.message.content.imageUrl)
  }
}

const handleFileClick = () => {
  if (props.message.content.fileUrl && props.message.content.fileName) {
    emit('fileClick', props.message.content.fileUrl, props.message.content.fileName)
  }
}

const handleVoiceClick = () => {
  if (props.message.content.fileUrl) {
    isVoicePlaying.value = !isVoicePlaying.value
    emit('voiceClick', props.message.content.fileUrl)
  }
}

const handleRetryMessage = () => {
  emit('retryMessage', props.message)
}
</script>

<style lang="scss" scoped>
.message-item {
  display: flex;
  margin-bottom: 16px;
  padding: 0 16px;

  &--left {
    justify-content: flex-start;
  }

  &--right {
    justify-content: flex-end;
  }

  &--center {
    justify-content: center;
  }

  &--system {
    .message-item__content {
      background: transparent;
    }
  }

  &__avatar {
    width: 40px;
    height: 40px;
    margin-right: 12px;
    flex-shrink: 0;

    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      object-fit: cover;
    }
  }

  &__content {
    max-width: 70%;
    min-width: 0;
  }

  &__sender {
    font-size: 12px;
    color: #999;
    margin-bottom: 4px;
    padding-left: 12px;
  }

  &__bubble {
    position: relative;
    padding: 12px 16px;
    border-radius: 18px;
    word-wrap: break-word;
    word-break: break-word;

    .message-item--left & {
      background: #f5f5f5;
      color: #333;
      
      &::before {
        content: '';
        position: absolute;
        left: -8px;
        top: 12px;
        width: 0;
        height: 0;
        border: 8px solid transparent;
        border-right-color: #f5f5f5;
      }
    }

    .message-item--right & {
      background: #007aff;
      color: white;
      
      &::after {
        content: '';
        position: absolute;
        right: -8px;
        top: 12px;
        width: 0;
        height: 0;
        border: 8px solid transparent;
        border-left-color: #007aff;
      }
    }

    .message-item--center & {
      background: rgba(0, 0, 0, 0.1);
      color: #666;
      border-radius: 12px;
      padding: 8px 12px;
      font-size: 12px;
      text-align: center;
    }

    &--failed {
      .message-item--right & {
        background: #ff4757;
      }
    }
  }

  &__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 4px;
    font-size: 11px;
    color: #999;

    .message-item--right & {
      flex-direction: row-reverse;
    }

    .message-item--center & {
      justify-content: center;
    }
  }
}

.message-content {
  &--text {
    line-height: 1.4;

    :deep(a) {
      color: inherit;
      text-decoration: underline;
    }
  }

  &--image {
    position: relative;
    padding: 0;
    border-radius: 12px;
    overflow: hidden;
    max-width: 200px;

    .message-image {
      width: 100%;
      height: auto;
      display: block;
      cursor: pointer;
      transition: transform 0.2s;

      &:hover {
        transform: scale(1.02);
      }
    }

    &__loading {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: white;
      font-size: 20px;
    }

    &__error {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 8px;
      color: #ff4757;
      font-size: 12px;
      cursor: pointer;
      background: rgba(0, 0, 0, 0.7);
      padding: 12px;
      border-radius: 8px;
      
      &:hover {
        background: rgba(0, 0, 0, 0.8);
      }
      
      i {
        font-size: 16px;
      }
    }

    .lazy-loading {
      opacity: 0.5;
      filter: blur(2px);
    }

    .lazy-loaded {
      opacity: 1;
      filter: none;
      transition: opacity 0.3s ease, filter 0.3s ease;
    }

    .lazy-error {
      opacity: 0.3;
      filter: grayscale(100%);
    }
  }

  &--file {
    display: flex;
    align-items: center;
    padding: 12px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.2s;

    &:hover {
      background: rgba(255, 255, 255, 0.2);
    }

    .file-icon {
      width: 40px;
      height: 40px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 8px;
      margin-right: 12px;
      font-size: 20px;
    }

    .file-info {
      flex: 1;
      min-width: 0;

      .file-name {
        font-weight: 500;
        margin-bottom: 2px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .file-size {
        font-size: 11px;
        opacity: 0.8;
      }
    }

    .file-download {
      margin-left: 8px;
      font-size: 16px;
      opacity: 0.8;
    }
  }

  &--voice {
    display: flex;
    align-items: center;
    padding: 12px;
    cursor: pointer;
    min-width: 120px;

    .voice-icon {
      width: 32px;
      height: 32px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 50%;
      margin-right: 12px;
      font-size: 16px;
    }

    .voice-duration {
      font-size: 12px;
      margin-right: 12px;
      opacity: 0.8;
    }

    .voice-waveform {
      display: flex;
      align-items: center;
      gap: 2px;
      flex: 1;

      .voice-wave {
        width: 2px;
        height: 12px;
        background: currentColor;
        opacity: 0.3;
        border-radius: 1px;
        transition: all 0.3s;

        &--active {
          opacity: 0.8;
          animation: voice-wave 1s infinite;
        }

        &:nth-child(2) { animation-delay: 0.1s; }
        &:nth-child(3) { animation-delay: 0.2s; }
        &:nth-child(4) { animation-delay: 0.3s; }
        &:nth-child(5) { animation-delay: 0.4s; }
      }
    }
  }

  &--system {
    text-align: center;
    font-size: 12px;
    color: #999;
  }

  &--unknown {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #ff4757;
    font-size: 12px;
  }
}

.message-time {
  font-size: 11px;
  color: #999;
  white-space: nowrap;
}

.message-status {
  display: flex;
  align-items: center;
  margin-left: 8px;

  &__icon {
    font-size: 12px;
    
    &--sending {
      color: #999;
      animation: spin 1s linear infinite;
    }

    &--sent {
      color: #999;
    }

    &--delivered {
      color: #007aff;
    }

    &--read {
      color: #007aff;
      position: relative;
      
      .el-icon-check {
        &:first-child {
          position: absolute;
          left: -2px;
        }
        
        &:last-child {
          position: relative;
          left: 2px;
        }
      }
    }

    &--failed {
      color: #ff4757;
      cursor: pointer;
      
      &:hover {
        opacity: 0.8;
      }
    }
  }
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes voice-wave {
  0%, 100% { height: 12px; }
  50% { height: 20px; }
}

// 响应式设计
@media (max-width: 768px) {
  .message-item {
    padding: 0 12px;
    margin-bottom: 12px;

    &__content {
      max-width: 80%;
    }

    &__avatar {
      width: 32px;
      height: 32px;
      margin-right: 8px;
    }

    &__bubble {
      padding: 10px 12px;
    }
  }

  .message-content {
    &--image {
      max-width: 150px;
    }

    &--file {
      padding: 10px;

      .file-icon {
        width: 32px;
        height: 32px;
        font-size: 16px;
        margin-right: 8px;
      }
    }
  }
}
</style>